home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / daemons / lpd / rmjob.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-19  |  6.7 KB  |  297 lines

  1. /*
  2.  * Copyright (c) 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that this notice is preserved and that due credit is given
  7.  * to the University of California at Berkeley. The name of the University
  8.  * may not be used to endorse or promote products derived from this
  9.  * software without specific prior written permission. This software
  10.  * is provided ``as is'' without express or implied warranty.
  11.  */
  12.  
  13. #ifndef lint
  14. static char sccsid[] = "@(#)rmjob.c    5.2 (Berkeley) 5/5/88";
  15. #endif /* not lint */
  16.  
  17. /*
  18.  * rmjob - remove the specified jobs from the queue.
  19.  */
  20.  
  21. #include "lp.h"
  22.  
  23. /*
  24.  * Stuff for handling lprm specifications
  25.  */
  26. extern char    *user[];        /* users to process */
  27. extern int    users;            /* # of users in user array */
  28. extern int    requ[];            /* job number of spool entries */
  29. extern int    requests;        /* # of spool requests */
  30. extern char    *person;        /* name of person doing lprm */
  31.  
  32. char    root[] = "root";
  33. int    all = 0;        /* eliminate all files (root only) */
  34. int    cur_daemon;        /* daemon's pid */
  35. char    current[40];        /* active control file name */
  36.  
  37. int    iscf();
  38.  
  39. rmjob()
  40. {
  41.     register int i, nitems;
  42.     int assasinated = 0;
  43.     struct direct **files;
  44.  
  45.     if ((i = pgetent(line, printer)) < 0)
  46.         fatal("cannot open printer description file");
  47.     else if (i == 0)
  48.         fatal("unknown printer");
  49.     if ((SD = pgetstr("sd", &bp)) == NULL)
  50.         SD = DEFSPOOL;
  51.     if ((LO = pgetstr("lo", &bp)) == NULL)
  52.         LO = DEFLOCK;
  53.     if ((LP = pgetstr("lp", &bp)) == NULL)
  54.         LP = DEFDEVLP;
  55.     if ((RP = pgetstr("rp", &bp)) == NULL)
  56.         RP = DEFLP;
  57.     RM = pgetstr("rm", &bp);
  58.  
  59.     /*
  60.      * If the format was `lprm -' and the user isn't the super-user,
  61.      *  then fake things to look like he said `lprm user'.
  62.      */
  63.     if (users < 0) {
  64.         if (getuid() == 0)
  65.             all = 1;    /* all files in local queue */
  66.         else {
  67.             user[0] = person;
  68.             users = 1;
  69.         }
  70.     }
  71.     if (!strcmp(person, "-all")) {
  72.         if (from == host)
  73.             fatal("The login name \"-all\" is reserved");
  74.         all = 1;    /* all those from 'from' */
  75.         person = root;
  76.     }
  77.  
  78.     if (chdir(SD) < 0)
  79.         fatal("cannot chdir to spool directory");
  80.     if ((nitems = scandir(".", &files, iscf, NULL)) < 0)
  81.         fatal("cannot access spool directory");
  82.  
  83.     if (nitems) {
  84.         /*
  85.          * Check for an active printer daemon (in which case we
  86.          *  kill it if it is reading our file) then remove stuff
  87.          *  (after which we have to restart the daemon).
  88.          */
  89.         if (lockchk(LO) && chk(current)) {
  90.             assasinated = kill(cur_daemon, SIGINT) == 0;
  91.             if (!assasinated)
  92.                 fatal("cannot kill printer daemon");
  93.         }
  94.         /*
  95.          * process the files
  96.          */
  97.         for (i = 0; i < nitems; i++)
  98.             process(files[i]->d_name);
  99.     }
  100.     chkremote();
  101.     /*
  102.      * Restart the printer daemon if it was killed
  103.      */
  104.     if (assasinated && !startdaemon(printer))
  105.         fatal("cannot restart printer daemon\n");
  106.     exit(0);
  107. }
  108.  
  109. /*
  110.  * Process a lock file: collect the pid of the active
  111.  *  daemon and the file name of the active spool entry.
  112.  * Return boolean indicating existence of a lock file.
  113.  */
  114. lockchk(s)
  115.     char *s;
  116. {
  117.     register FILE *fp;
  118.     register int i, n;
  119.  
  120.     if ((fp = fopen(s, "r")) == NULL)
  121.         if (errno == EACCES)
  122.             fatal("can't access lock file");
  123.         else
  124.             return(0);
  125.     if (!getline(fp)) {
  126.         (void) fclose(fp);
  127.         return(0);        /* no daemon present */
  128.     }
  129.     cur_daemon = atoi(line);
  130.     if (kill(cur_daemon, 0) < 0) {
  131.         (void) fclose(fp);
  132.         return(0);        /* no daemon present */
  133.     }
  134.     for (i = 1; (n = fread(current, sizeof(char), sizeof(current), fp)) <= 0; i++) {
  135.         if (i > 5) {
  136.             n = 1;
  137.             break;
  138.         }
  139.         sleep(i);
  140.     }
  141.     current[n-1] = '\0';
  142.     (void) fclose(fp);
  143.     return(1);
  144. }
  145.  
  146. /*
  147.  * Process a control file.
  148.  */
  149. process(file)
  150.     char *file;
  151. {
  152.     FILE *cfp;
  153.  
  154.     if (!chk(file))
  155.         return;
  156.     if ((cfp = fopen(file, "r")) == NULL)
  157.         fatal("cannot open %s", file);
  158.     while (getline(cfp)) {
  159.         switch (line[0]) {
  160.         case 'U':  /* unlink associated files */
  161.             if (from != host)
  162.                 printf("%s: ", host);
  163.             printf(unlink(line+1) ? "cannot dequeue %s\n" :
  164.                 "%s dequeued\n", line+1);
  165.         }
  166.     }
  167.     (void) fclose(cfp);
  168.     if (from != host)
  169.         printf("%s: ", host);
  170.     printf(unlink(file) ? "cannot dequeue %s\n" : "%s dequeued\n", file);
  171. }
  172.  
  173. /*
  174.  * Do the dirty work in checking
  175.  */
  176. chk(file)
  177.     char *file;
  178. {
  179.     register int *r, n;
  180.     register char **u, *cp;
  181.     FILE *cfp;
  182.  
  183.     /*
  184.      * Check for valid cf file name (mostly checking current).
  185.      */
  186.     if (strlen(file) < 7 || file[0] != 'c' || file[1] != 'f')
  187.         return(0);
  188.  
  189.     if (all && (from == host || !strcmp(from, file+6)))
  190.         return(1);
  191.  
  192.     /*
  193.      * get the owner's name from the control file.
  194.      */
  195.     if ((cfp = fopen(file, "r")) == NULL)
  196.         return(0);
  197.     while (getline(cfp)) {
  198.         if (line[0] == 'P')
  199.             break;
  200.     }
  201.     (void) fclose(cfp);
  202.     if (line[0] != 'P')
  203.         return(0);
  204.  
  205.     if (users == 0 && requests == 0)
  206.         return(!strcmp(file, current) && isowner(line+1, file));
  207.     /*
  208.      * Check the request list
  209.      */
  210.     for (n = 0, cp = file+3; isdigit(*cp); )
  211.         n = n * 10 + (*cp++ - '0');
  212.     for (r = requ; r < &requ[requests]; r++)
  213.         if (*r == n && isowner(line+1, file))
  214.             return(1);
  215.     /*
  216.      * Check to see if it's in the user list
  217.      */
  218.     for (u = user; u < &user[users]; u++)
  219.         if (!strcmp(*u, line+1) && isowner(line+1, file))
  220.             return(1);
  221.     return(0);
  222. }
  223.  
  224. /*
  225.  * If root is removing a file on the local machine, allow it.
  226.  * If root is removing a file from a remote machine, only allow
  227.  * files sent from the remote machine to be removed.
  228.  * Normal users can only remove the file from where it was sent.
  229.  */
  230. isowner(owner, file)
  231.     char *owner, *file;
  232. {
  233.     if (!strcmp(person, root) && (from == host || !strcmp(from, file+6)))
  234.         return(1);
  235.     if (!strcmp(person, owner) && !strcmp(from, file+6))
  236.         return(1);
  237.     if (from != host)
  238.         printf("%s: ", host);
  239.     printf("%s: Permission denied\n", file);
  240.     return(0);
  241. }
  242.  
  243. /*
  244.  * Check to see if we are sending files to a remote machine. If we are,
  245.  * then try removing files on the remote machine.
  246.  */
  247. chkremote()
  248. {
  249.     register char *cp;
  250.     register int i, rem;
  251.     char buf[BUFSIZ];
  252.  
  253.     if (*LP || RM == NULL)
  254.         return;    /* not sending to a remote machine */
  255.  
  256.     /*
  257.      * Flush stdout so the user can see what has been deleted
  258.      * while we wait (possibly) for the connection.
  259.      */
  260.     fflush(stdout);
  261.  
  262.     sprintf(buf, "\5%s %s", RP, all ? "-all" : person);
  263.     cp = buf;
  264.     for (i = 0; i < users; i++) {
  265.         cp += strlen(cp);
  266.         *cp++ = ' ';
  267.         strcpy(cp, user[i]);
  268.     }
  269.     for (i = 0; i < requests; i++) {
  270.         cp += strlen(cp);
  271.         (void) sprintf(cp, " %d", requ[i]);
  272.     }
  273.     strcat(cp, "\n");
  274.     rem = getport(RM);
  275.     if (rem < 0) {
  276.         if (from != host)
  277.             printf("%s: ", host);
  278.         printf("connection to %s is down\n", RM);
  279.     } else {
  280.         i = strlen(buf);
  281.         if (write(rem, buf, i) != i)
  282.             fatal("Lost connection");
  283.         while ((i = read(rem, buf, sizeof(buf))) > 0)
  284.             (void) fwrite(buf, 1, i, stdout);
  285.         (void) close(rem);
  286.     }
  287. }
  288.  
  289. /*
  290.  * Return 1 if the filename begins with 'cf'
  291.  */
  292. iscf(d)
  293.     struct direct *d;
  294. {
  295.     return(d->d_name[0] == 'c' && d->d_name[1] == 'f');
  296. }
  297.